﻿using System;
using System.Reflection;
using System.Threading;
using System.Windows;
using Hardcodet.Wpf.TaskbarNotification.Interop;
using Microsoft.Practices.Unity;

namespace CustomerAssistant
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        bool IsTaskbarIconCreated = false;

        /// <summary>
        /// 此处一定要用静态全局变量,如果使用局部变量则会自动回收(回收的时机无法确定),失去效果
        /// </summary>
        static Mutex mutex = null;

        private NotifyIconData iconData;

        /// <summary>
        /// Receives messages from the taskbar icon.
        /// </summary>
        private readonly WindowMessageSink messageSink;

        public App()
        {
            messageSink = new WindowMessageSink(NotifyIconVersion.Win2000);
            messageSink.MouseEventReceived += new Action<MouseEvent>(messageSink_MouseEventReceived);
            messageSink.TaskbarCreated += new Action(messageSink_TaskbarCreated);
            messageSink.ChangeToolTipStateRequest += new Action<bool>(messageSink_ChangeToolTipStateRequest);
            messageSink.BalloonToolTipChanged += new Action<bool>(messageSink_BalloonToolTipChanged);
        }

        const IconDataMembers members = IconDataMembers.Message
                                          | IconDataMembers.Icon
                                          | IconDataMembers.Tip;

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            System.Diagnostics.Process.Start("CAssistantUpdateSvc.exe");
            if (!SingletonCheck())
            {
                //已经有一个实例运行了
                Application.Current.Shutdown();
            }
            setupContainer();

            lock (this)
            {
                if (!IsTaskbarIconCreated)
                {
                    iconData = NotifyIconData.CreateDefault(messageSink.MessageWindowHandle);
                    iconData.ToolTipText = "客户助手v1.0";
                    var icon = CustomerAssistant.Properties.Resource.status_icon;
                    iconData.IconHandle = icon.Handle;
                    //write initial configuration
                    var status = TrayNotifyUtil.WriteIconData(ref iconData, NotifyCommand.Add, members);
                    if (!status)
                    {
                        LogHelper.LogError("不能创建托盘图标", true);
                    }
                    IsTaskbarIconCreated = true;
                }
            }
            var wnd = new Window();
            wnd.Icon = SysHelper.GetImageSource(CustomerAssistant.Properties.Resource.itour_helper_32_32);
            wnd.ShowInTaskbar = true;
            wnd.Title = "用户登录";
            wnd.ResizeMode = ResizeMode.NoResize;
            var login = new Login();
            wnd.Width = login.Width;
            wnd.Height = login.Height;
            wnd.Content = login;
            wnd.AllowsTransparency = true;
            wnd.WindowStyle = WindowStyle.None;
            wnd.Left = (SystemParameters.PrimaryScreenWidth - login.Width) / 2;
            wnd.Top = (SystemParameters.WorkArea.Height - login.Height) / 2;
            wnd.Loaded += new RoutedEventHandler((a, b) =>
            {
                login.SettingInit();
                login.AutoLogin();
            });
            wnd.Show();
        }

        private void Application_Exit(object sender, ExitEventArgs e)
        {
            mutex.Close();
            messageSink.Dispose();
            TrayNotifyUtil.WriteIconData(ref iconData, NotifyCommand.Delete, members);
        }

        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            LogHelper.LogError(e.Exception.Message, e.Exception);
            e.Handled = true;
        }

        protected override void OnDeactivated(EventArgs e)
        {
            base.OnDeactivated(e);
            TrayNotifyUtil.CloseTrayMenu();
        }

        private void setupContainer()
        {
            IUnityContainer container = SysHelper.UnityContainer;
            container.RegisterType<MessageWindow>(new ContainerControlledLifetimeManager());
        }

        #region 托盘事件处理

        private void messageSink_BalloonToolTipChanged(bool obj)
        {
            throw new NotImplementedException();
        }

        private void messageSink_ChangeToolTipStateRequest(bool obj)
        {
            throw new NotImplementedException();
        }

        private void messageSink_TaskbarCreated()
        {
        }

        private void messageSink_MouseEventReceived(MouseEvent obj)
        {
            switch (obj)
            {
                case MouseEvent.BalloonToolTipClicked: break;
                case MouseEvent.IconDoubleClick: break;
                case MouseEvent.IconLeftMouseUp:
                    TrayNotifyUtil.StopFlashTrayIcon();
                    OrderMonitor.Notice();
                    break;
                case MouseEvent.IconLeftMouseDown: break;
                case MouseEvent.IconMiddleMouseDown: break;
                case MouseEvent.IconMiddleMouseUp: break;
                case MouseEvent.IconRightMouseDown: break;
                case MouseEvent.IconRightMouseUp:
                    //弹出右击菜单
                    TrayNotifyUtil.PopupTrayMenu(messageSink);
                    break;
                case MouseEvent.MouseMove: break;
            }
        }

        #endregion 托盘事件处理

        #region 单例检测

        private bool SingletonCheck()
        {
            /*
             * 参看<<windows核心编程第五版>>,理论上不应该这样写,因为有可能被DOS攻击,应该私有化对象命名空间,但私有化仅在
             * Vista以上版本才支持
             * http://msdn.microsoft.com/en-us/library/windows/desktop/ms684295(v=vs.85).aspx
             * 及CreatePrivateNamespace函数
             */
            bool noInstance;
            mutex = new Mutex(true, "Global\\" + Assembly.GetExecutingAssembly().FullName, out noInstance);
            return noInstance;
        }

        #endregion 单例检测
    }
}